#pragma once

#include <cstdint>
#include <string>

namespace ly {

class Variant {
 public:
  enum type {
    t_nil,
    t_bool,
    t_char,
    t_uint8,
    t_int8,
    t_uint16,
    t_int16,
    t_uint32,
    t_int32,
    t_uint64,
    t_int64,
    t_float,
    t_double,
    t_string,
  };

  // 默认构造：初始化为 nil 类型
  Variant() : m_type(type::t_nil) {}

  // 各种类型的构造函数
  Variant(bool v) : m_type(type::t_bool) { m_var.m_bool = v; }
  Variant(char v) : m_type(type::t_char) { m_var.m_char = v; }
  Variant(uint8_t v) : m_type(type::t_uint8) { m_var.m_uint8 = v; }
  Variant(int8_t v) : m_type(type::t_int8) { m_var.m_int8 = v; }
  Variant(uint16_t v) : m_type(type::t_uint16) { m_var.m_uint16 = v; }
  Variant(int16_t v) : m_type(type::t_int16) { m_var.m_int16 = v; }
  Variant(uint32_t v) : m_type(type::t_uint32) { m_var.m_uint32 = v; }
  Variant(int32_t v) : m_type(type::t_int32) { m_var.m_int32 = v; }
  Variant(uint64_t v) : m_type(type::t_uint64) { m_var.m_uint64 = v; }
  Variant(int64_t v) : m_type(type::t_int64) { m_var.m_int64 = v; }
  Variant(float v) : m_type(type::t_float) { m_var.m_float = v; }
  Variant(double v) : m_type(type::t_double) { m_var.m_double = v; }
  Variant(const std::string& s) : m_type(type::t_string), m_string(s) {}
  Variant(const char* s) : m_type(type::t_string), m_string(s) {}

  // Getter 方法（带类型检查）
  bool to_bool() const;
  std::string to_string() const;

  double to_double() const;
  float to_float() const;

  uint8_t to_uint8() const;
  int8_t to_int8() const;

  uint16_t to_uint16() const;
  int16_t to_int16() const;

  uint32_t to_uint32() const;
  int32_t to_int32() const;

  uint64_t to_uint64() const;
  int64_t to_int64() const;

  // 获取当前类型
  type get_type() const { return m_type; }

  // 赋值操作符
  Variant& operator=(bool v);
  Variant& operator=(char v);
  Variant& operator=(uint8_t v);
  Variant& operator=(int8_t v);
  Variant& operator=(uint16_t v);
  Variant& operator=(int16_t v);
  Variant& operator=(uint32_t v);
  Variant& operator=(int32_t v);
  Variant& operator=(uint64_t v);
  Variant& operator=(int64_t v);
  Variant& operator=(float v);
  Variant& operator=(double v);
  Variant& operator=(const std::string& s);
  Variant& operator=(const char* s);

  // 比较操作符
  bool operator==(const Variant& v) const;
  bool operator!=(const Variant& v) const;
  bool operator<(const Variant& v) const;
  bool operator>(const Variant& v) const;
  bool operator<=(const Variant& v) const;
  bool operator>=(const Variant& v) const;

  // 算术操作符
  Variant operator+(const Variant& v) const;
  Variant operator-(const Variant& v) const;
  Variant operator*(const Variant& v) const;
  Variant operator/(const Variant& v) const;

 private:
  type m_type;

  union Var {
    bool m_bool;
    char m_char;
    uint8_t m_uint8;
    int8_t m_int8;
    uint16_t m_uint16;
    int16_t m_int16;
    uint32_t m_uint32;
    int32_t m_int32;
    uint64_t m_uint64;
    int64_t m_int64;
    float m_float;
    double m_double;

    // 默认构造函数
    Var() {}
  } m_var;

  std::string m_string;
};

}  // namespace ly
